<template>
  <div class="qs-y-table-card">
    <el-table ref="tableSortRef" v-loading="props.listLoading" border :data="props.list" stripe @selection-change="handleSelectionChange">
      <el-table-column align="center" label="序号" width="55">
        <template #default="{ $index }">
          {{ $index + 1 }}
        </template>
      </el-table-column>

      <el-table-column
        v-for="(item, index) in props.finallyColumns"
        :key="index"
        align="center"
        :fixed="item.fixed"
        :label="item.label"
        :min-width="item.minWidth || 150"
        show-overflow-tooltip
        :sortable="item.sortable"
      >
        <template #default="{ row }">
          <template v-if="item.component">
            <component
              :is="getComponent(item.component)"
              v-if="getComponent(item.component)"
              v-bind="getComponentProps(item, row)"
              :model-value="formatColumnValue(row, item)"
              :row="row"
              @update:model-value="(val) => handleComponentValueUpdate(val, row, item)"
            />
            <template v-else>
              <el-tooltip :content="'组件未找到: ' + item.component" effect="dark" placement="top">
                <span class="component-error">组件加载失败</span>
              </el-tooltip>
            </template>
          </template>
          <template v-else>
            <span v-if="item.prop">
              <template v-if="item.dictionary">
                {{ item.dictionary[getNestedValue(row, item.prop)] || getNestedValue(row, item.prop) || '-' }}
              </template>
              <template v-else>
                {{ getNestedValue(row, item.prop) || '-' }}
              </template>
            </span>
            <span v-else>-</span>
          </template>
        </template>
      </el-table-column>

      <slot name="operation">
        <el-table-column align="center" fixed="right" label="操作" width="150">
          <template #default="{ row }">
            <el-button size="small" text @click="handleEdit(row)">编辑</el-button>
            <el-button size="small" text type="danger" @click="handleDelete(row)">删除</el-button>
          </template>
        </el-table-column>
      </slot>

      <template #empty>
        <el-empty class="vab-data-empty" description="暂无数据" />
      </template>
    </el-table>

    <el-pagination
      background
      :current-page="props.queryForm.page"
      :layout="props.layout"
      :page-size="props.queryForm.limit"
      :total="props.total"
      @current-change="handleCurrentChange"
      @size-change="handleSizeChange"
    />

    <el-dialog v-model="dialogVisible" :title="dialogTitle" width="80%">
      <component
        :is="dialogComponent"
        v-if="dialogVisible && dialogComponent"
        :dialog-row="dialogRow"
        @update-surround="handleSurroundUpdate"
      />
      <template #footer>
        <span class="dialog-footer">
          <el-button @click="dialogVisible = false">取消</el-button>
          <el-button type="primary" @click="saveEdit">确定</el-button>
        </span>
      </template>
    </el-dialog>
  </div>
</template>

<script lang="ts" setup>
import { ElMessage } from 'element-plus'
import { ref, resolveComponent } from 'vue'
import { type ComponentType, componentMap } from '../componentMap'
import Public from '/@/api/public'

// 类型定义
interface TableColumn {
  dictionary?: Record<string, string>
  label: string
  prop: string
  fixed?: boolean
  minWidth?: number | string
  sortable?: boolean
  component?: ComponentType
  componentProps?: Record<string, any> | ((row: any) => Record<string, any>)
  componentEvents?: Record<string, (value: any, row: any) => Promise<boolean> | boolean>
  outOfLine?: boolean
  tagLabel?: string
  format?: (row: any) => any
}

interface QueryForm {
  page: number
  limit: number
  [key: string]: any
}

interface Props {
  list: any[]
  listLoading: boolean
  queryForm: QueryForm
  total: number
  layout: string
  finallyColumns: TableColumn[]
}

// Props 定义
const props = defineProps<Props>()

// Emits 定义
const emit = defineEmits<{
  (e: 'update:query-form', value: QueryForm): void
  (e: 'handle-edit', value: any): void
  (e: 'handle-delete', value: string): void
  (e: 'handle-size-change', value: number): void
  (e: 'handle-current-change', value: number): void
  (e: 'handle-selection-change', value: any[]): void
}>()

// 状态管理
const tableSortRef = ref<any>(null)
const dialogVisible = ref(false)
const dialogTitle = ref('')
const dialogComponent = ref<string | null>(null)
const dialogRow = ref<any>({})

// 工具函数
const getComponent = (componentName: string) => {
  // 1. 先从 componentMap 中查找
  if (componentName in componentMap) {
    return componentMap[componentName as ComponentType]
  }
  // 2. 如果不在 componentMap 中，尝试从全局组件中获取
  try {
    return resolveComponent(componentName)
  } catch {
    console.warn(`组件 ${componentName} 未找到`)
    return null
  }
}

const getComponentProps = (item: TableColumn, row: any) => {
  const props = item.componentProps ? (typeof item.componentProps === 'function' ? item.componentProps(row) : item.componentProps) : {}
  return props
}

const getNestedValue = (obj: any, path: string) => {
  if (!obj || !path) return null
  const value = path.split('.').reduce((acc, part) => {
    return acc && typeof acc === 'object' ? acc[part] : null
  }, obj)
  return value
}

const formatColumnValue = (row: any, item: TableColumn) => {
  if (item.format) {
    return item.format(row)
  }
  const value = getNestedValue(row, item.prop)
  if (item.component === ('Tags' as ComponentType) && Array.isArray(value)) {
    return value.map((tag: any) => tag.value || tag)
  }
  return value
}

// 事件处理
const openDialog = (componentName: string, title: string, row: any) => {
  dialogTitle.value = title
  dialogComponent.value = componentName
  dialogRow.value = row
  dialogVisible.value = true
}

const handleEdit = (row: any) => {
  emit('handle-edit', row)
}

const handleDelete = (row: any) => {
  emit('handle-delete', row.id)
}

const handleCurrentChange = (value: number) => {
  emit('handle-current-change', value)
}

const handleSizeChange = (value: number) => {
  emit('handle-size-change', value)
}

const handleSelectionChange = (selection: any[]) => {
  emit('handle-selection-change', selection)
}

const saveEdit = async () => {
  try {
    await Public.editApi({ url: '/api/hotelManagement', data: dialogRow.value })
    dialogVisible.value = false
    ElMessage.success('保存成功!')
  } catch {
    ElMessage.error('保存失败')
  }
}

const handleSurroundUpdate = (data: string[]) => {
  dialogRow.value.surround = data
}

// 类型定义
type ComponentValueUpdateHandler = (value: any, row: any, column: TableColumn) => Promise<void>

const handleComponentValueUpdate: ComponentValueUpdateHandler = async (value, row, column) => {
  if (column.componentEvents?.['update:modelValue']) {
    try {
      const result = await column.componentEvents['update:modelValue'](value, row)
      if (result) {
        // 保持当前页面状态和数据，只添加时间戳触发刷新
        emit('update:query-form', {
          ...props.queryForm,
          _timestamp: Date.now(),
        })
      }
    } catch {
      ElMessage.error('更新失败')
    }
  }
}

defineExpose({
  tableSortRef,
  dialogVisible,
  openDialog,
  saveEdit,
})
</script>

<script lang="ts">
export default {
  name: 'QsTable',
}
</script>

<style scoped>
.qs-y-table-card {
  background-color: var(--el-bg-color);
  border-radius: 4px;
  padding: 20px;
}

.el-pagination {
  margin-top: 15px;
  justify-content: flex-end;
}

.component-error {
  color: var(--el-color-danger);
  font-size: 12px;
}
</style>
